package com.dd.stack.common.util.enumeration;

//import com.dd.stack.mybatisplus.pojo.enumeration.DOTypeEnum;
//import com.dd.stack.mybatisplus.pojo.enumeration.IntCodeEnum;

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author liuxianmeng
 * @CreateTime 2025/6/8 11:43
 * @Description 枚举注册器 版本1.0(First) 放在模块服务下注册模块服务中的枚举类 在Controller中建立一个接口返回所有枚举信息供前端使用
 *
 *              如： com.dd.stack.mybatisplus.config.enumeration.EnumRegistrar
 *                  @RestController
 *                  @RequiredArgsConstructor
 *                  @RequestMapping("/enum")
 *                  @Api(tags = "提供全量枚举信息")
 *                  public class EnumController {
 *                      @GetMapping("/list")
 *                      @ApiOperation("提供全量枚举信息")
 *                      public ApiResponse<Map<String, Map<String, String>>> list(){
 *                          return ApiResponse.success(EnumRegistrar.enumMap());
 *                      }
 *                  }
 */
public class EnumRegistrar {

    /**
     * 枚举映射表
     */
    private static final Map<String, Map<String, String>> ENUM_MAP = new LinkedHashMap<>();

    static {
        // 手动注册所有业务枚举
        //registerEnum(DOTypeEnum.class);
        //registerEnum(IntCodeEnum.class);
        // 其他枚举...
    }

    /**
     * 获取所有枚举映射（不可修改视图）
     *
     * 【直接返回ENUM_MAP的风险】
     * 调用方可以通过这个引用直接修改ENUM_MAP的内容（如put/remove）
     * 破坏类的封装性，导致不可控的副作用
     * 多线程环境下可能引发并发修改问题
     *
     * 【Collections.unmodifiableMap()的作用】
     * 创建视图：返回一个只读视图（wrapper），底层仍然指向原始ENUM_MAP
     * 防篡改：任何通过该视图尝试修改的操作（如put/remove）会抛出UnsupportedOperationException
     * 实时同步：视图会反映原始Map的最新变化（因为是包装器，不是拷贝）
     */
    public static Map<String, Map<String, String>> enumMap() {
        return Collections.unmodifiableMap(ENUM_MAP);
    }

    /**
     * 注册单个枚举类
     *
     * @param enumClass 必须实现 CodedEnum 和 DescribableEnum 接口
     */
    public static <C, T extends Enum<T> & CodedEnum<C> & DescribableEnum> void registerEnum(Class<T> enumClass) {
        Map<String, String> enumCodeDescMap = Arrays.stream(enumClass.getEnumConstants())
                .collect(Collectors.toMap(
                        e -> e.getCode().toString(),
                        DescribableEnum::getDescription,
                        // 这是合并函数(merge function)，处理键冲突的情况
                        // 如果有两个枚举项的code相同，保留旧值(oldVal)
                        (oldVal, newVal) -> oldVal,
                        // 使用LinkedHashMap而不是默认的HashMap 可以保持枚举项原始的顺序
                        LinkedHashMap::new
                ));
        ENUM_MAP.put(enumClass.getSimpleName(), enumCodeDescMap);
    }
}
